﻿using IdentityModel;
using IdentityModel.Client;
using System.Diagnostics;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;

namespace MaBlaApp.Data;

/// <summary>
/// 手机验证码登录功能模块
/// </summary>
public class Ids4Client
{
    private readonly HttpClient _client;

    public Ids4Client(HttpClient httpClient)
    {
        _client = httpClient;
    }

    /// <summary>
    /// 发送验证码到手机号
    /// </summary>
    /// <param name="phoneNumber"></param>
    /// <returns></returns>
    public async Task<string> SendPhoneCodeAsync(string phoneNumber)
    {
        string url = $"api/PhoneCodeLogin/SendPhoneCode?phoneNumber={phoneNumber}";

        string result = await _client.GetStringAsync(url);

        return result;
    }

    /// <summary>
    /// 手机验证码登录
    /// </summary>
    /// <param name="phoneNumber">手机号</param>
    /// <param name="verificationCode">验证码</param>
    /// <returns></returns>
    public async Task<LoginUserInfo> PhoneCodeLogin(string phoneNumber, string verificationCode)
    {
        var request = new DiscoveryDocumentRequest()
        {
            Policy = new DiscoveryPolicy()
            {
                //本地调试抓包
                RequireHttps = false
            }
        };

        //发现端点
        var discovery = await _client.GetDiscoveryDocumentAsync(request);

        if (discovery.IsError)
        {
            Debug.WriteLine($"访问Identity Server 4服务器失败, Error={discovery.Error}");
            return null;
        }

        //填写登录参数，必须跟Identity Server 4服务器Config.cs定义一致
        var requestParams = new Dictionary<string, string>
        {
            ["client_Id"] = "PhoneCode",
            ["client_secret"] = "PhoneCode.Secret",
            ["grant_type"] = "PhoneCodeGrantType",
            ["scope"] = "openid profile scope1 role",
            ["PhoneNumber"] = phoneNumber,
            ["VerificationCode"] = verificationCode
        };

        //请求获取token
        var tokenResponse = await _client.RequestTokenRawAsync(discovery.TokenEndpoint, requestParams);
        if (tokenResponse.IsError)
        {
            Debug.WriteLine($"请求获取token失败, Error={tokenResponse.Error}");
            return null;
        }

        string userInfoJson = "";

        //设置Http认证头
        _client.SetBearerToken(tokenResponse.AccessToken);

        //获取用户信息
        //var userInfoResponse = await _client.GetAsync(discovery.UserInfoEndpoint);
        //if (!userInfoResponse.IsSuccessStatusCode)
        //{
        //    //scope必须包含profile才能获取到用户信息
        //    //如果客户端请求scope没有profile，返回403拒绝访问
        //    Debug.WriteLine($"获取用户信息失败, StatusCode={userInfoResponse.StatusCode}");
        //}
        //else
        //{
        //    // {"sub":"d2f64bb2-789a-4546-9107-547fcb9cdfce","name":"Alice Smith","given_name":"Alice","family_name":"Smith","website":"http://alice.com","role":["Admin","Guest"],"preferred_username":"alice"}
        //    userInfoJson = await userInfoResponse.Content.ReadAsStringAsync();
        //    Debug.WriteLine($"获取用户信息成功, {userInfoJson}");
        //}
        //MAUI Blazor客户端PhoneCodeGrantType方式访问Id4，只获取到sub nation

        var jwtSecurityToken = new JwtSecurityToken(tokenResponse.AccessToken);

        LoginUserInfo loginUserInfo = new LoginUserInfo();

        loginUserInfo.AccessToken = tokenResponse.AccessToken;
        loginUserInfo.RefreshToken = tokenResponse.RefreshToken;
        loginUserInfo.ExpiresIn = DateTimeOffset.Now.AddSeconds(tokenResponse.ExpiresIn);

        //用户名
        loginUserInfo.Username = jwtSecurityToken.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Name)?.Value;

        //用户ID
        var claimId = jwtSecurityToken.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject);
        if (Guid.TryParse(claimId?.Value, out Guid userId))
            loginUserInfo.UserId = $"{userId}";

        //角色
        //id4返回的角色是字符串数组或者字符串
        var roleNames = jwtSecurityToken.Claims.Where(x => x.Type == JwtClaimTypes.Role).Select(x => x.Value);
        loginUserInfo.UserRole = string.Join(",", roleNames);

        return loginUserInfo;
    }
}
